package cn.iune.erp.accounting;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.justep.baas.Utils;
import com.justep.baas.data.Row;
import com.justep.baas.data.RowState;
import com.justep.baas.data.Table;
import com.justep.baas.data.Transform;


@Transactional
@Service
public class AccountVoucherServiceImpl implements IAccountVoucherService {
	
	@Autowired
	private IAccountVoucherDao dao;
	@Autowired
	private IAccountVoucherDetailDao detailDao;
	

	@Transactional
	@Override
	public void insert(AccountVoucher a) {
		// TODO Auto-generated method stub
		dao.insert(a);
	}

	@Transactional
	@Override
	public void update(AccountVoucher a) {
		// TODO Auto-generated method stub
		dao.update(a);
	}
	
	@Transactional
	@Override
	public void delete(String fID) {
		dao.delete(fID);
	}

	@Override
	public AccountVoucher getByID(String fID) {
		return dao.getByID(fID);
	}

	@Transactional
	@Override
	public JSONObject save(JSONObject object) throws ParseException  {
		// JSON转换Table
		Table table = Transform.jsonToTable(object);
		
		JSONObject data = new JSONObject();
		data.put("concept", table.getTableName());
		JSONArray rows = new JSONArray();
		
		List<Row> list = table.getRows();
		for(Row row : list){
			JSONObject javaObject= Transform.rowToJavaObject(table, row);
			AccountVoucher obj = JSON.toJavaObject(javaObject, AccountVoucher.class);
			if(RowState.NEW.equals(obj.getRowState())){
				dao.insert(obj);
			}
			if(RowState.DELETE.equals(obj.getRowState())){
				dao.delete(obj.getfID());
			}
			if(RowState.EDIT.equals(obj.getRowState())){
				AccountVoucher objNew = dao.update(obj);
				//返回+1后的version到前台BizData中进行刷新，使得前台的version与后台的一致。
				///////////////////////////////////////////////////////////////////////
				JSONObject jsonRow = new JSONObject();
				jsonRow.put("id", obj.getfID());
				jsonRow.put("version", objNew.getVersion());
				rows.add(jsonRow);
				//////////////////////////////////////////////////////////////////////
			}
		}
		
		data.put("rows", rows);
		
		return data;
	}
	
	@Transactional
	@Override
	public JSONObject saveDetail(JSONObject object) throws ParseException {
		// TODO Auto-generated method stub
		// JSON转换Table
		Table table = Transform.jsonToTable(object);
//		List<ShopCart> list = rowsToList(table.getRows());
		
		//System.out.println(table.getTableName());
		
		JSONObject json = new JSONObject();
		json.put("concept", table.getTableName());
		JSONArray rows = new JSONArray();
		
		List<Row> list = table.getRows();
		for(Row row : list){
			JSONObject javaObject= Transform.rowToJavaObject(table, row);
			AccountVoucherDetail obj = JSON.toJavaObject(javaObject, AccountVoucherDetail.class);
			if(RowState.NEW.equals(obj.getRowState())){
				detailDao.insert(obj);
			}
			if(RowState.DELETE.equals(obj.getRowState())){
				detailDao.delete(obj.getfID());
			}
			if(RowState.EDIT.equals(obj.getRowState())){
				AccountVoucherDetail objNew = detailDao.update(obj);
				JSONObject jsonRow = new JSONObject();
				jsonRow.put("id", obj.getfID());
				jsonRow.put("version", objNew.getVersion());
				rows.add(jsonRow);
			}
		}
		
		json.put("rows", rows);
		
		return json;
	}
	

	
	@Override
	public AccountVoucher getByNo(String voucherNo, String enterpriseNo) {
		return dao.getByNo(voucherNo, enterpriseNo);
	}

	@Transactional
	@Override
	public int confirm(String fID) {
		// TODO Auto-generated method stub
		AccountVoucher a = dao.getByID(fID);
		this.confirm(a);
		return 0;
	}
	@Transactional
	@Override
	public int confirm(AccountVoucher a) {
		// TODO Auto-generated method stub
		a.setState("confirm");
		dao.update(a);
		return 0;
	}

	@Transactional
	@Override
	public int active(String fID) {
		// TODO Auto-generated method stub
		AccountVoucher a = dao.getByID(fID);
		this.active(a);
		return 0;
	}
	@Transactional
	@Override
	public int active(AccountVoucher a) {
		// TODO Auto-generated method stub
		a.setState("active");
		dao.update(a);
		return 0;
	}


	@Transactional
	@Override
	public int open(String fID) {
		AccountVoucher a = dao.getByID(fID);
		this.open(a);
		return 0;
	}
	@Transactional
	@Override
	public int open(AccountVoucher a) {
		// TODO Auto-generated method stub
		a.setStatus("open");
		dao.update(a);
		return 0;
	}


	@Transactional
	@Override
	public int close(String fID) {
		AccountVoucher a = dao.getByID(fID);
		this.close(a);
		return 0;
	}
	@Transactional
	@Override
	public int close(AccountVoucher a) {
		// TODO Auto-generated method stub
		a.setStatus("close");
		dao.update(a);
		return 0;
	}

	@Transactional
	@Override
	public int agreeIt(AccountVoucher a,String cUsercode,String cUsername, String userId) {
		// TODO Auto-generated method stub

		a.setAudit("confirm");
		a.setConfirmDate(Utils.getCurrentDate());
		
		a.settUsercode(cUsercode);
		a.settUsername(cUsername);
		a.settDatetime(Utils.getCurrentDateTime());

		dao.update(a);

		//执行更新操作
		this.doIt(a);

		return 0;
	}

	@Transactional
	@Override
	public int agreeIt(String fID,String cUsercode,String cUsername, String userId) {
		
		// TODO Auto-generated method stub
		AccountVoucher a = dao.getByID(fID);
		
		this.agreeIt(a, cUsercode, cUsername,  userId);
		 
		return 0;
	}
	
	@Transactional
	@Override
	public int unAgree(AccountVoucher a) {
		// TODO Auto-generated method stub
		
		a.setAudit("active");
		a.setConfirmDate(null);
		
		a.settUsercode(null);
		a.settUsername(null);
		a.settDatetime(null);
		
		dao.update(a);
		
		//执行更新操作
		this.unDo(a);

		return 0;
	}
	
	@Transactional
	@Override
	public int unAgree(String fID) {
		// TODO Auto-generated method stub

		//判断是否可以撤销
		AccountVoucher a = dao.getByID(fID);
		
		this.unAgree(a);
		
		return 0;
	}
	
	@Transactional
	@Override
	public int doIt(AccountVoucher a) {
		return 0;
	}
	
	@Transactional
	@Override
	public int unDo(AccountVoucher a) {
		return 0;
	}

	@Transactional
	@Override
	public int updateMaxDetailNo(
			String fID
			,int maxDetailNo){
		
		AccountVoucher a = dao.getByID(fID);
		a.setMaxDetailNo( maxDetailNo );
		//更新数据库入库数量
		dao.update(a);
		return 0;
	}	
	
	@Transactional
	@Override
	public int updateMaxDetailNo(
			String voucherNo
			,String billType
			,String enterpriseNo
			,int maxDetailNo){
		
		AccountVoucher a = dao.getByNo(voucherNo, enterpriseNo);
		a.setMaxDetailNo( maxDetailNo );
		//更新数据库入库数量
		dao.update(a);
		return 0;
	}	
	
	//自动生成编号
	@Override
	public AccountVoucher packing(
			String billType
			,String billTypeName 
			,String systemCode 
			,int flowType 
			,int direction 
			,String autoCode 
			,String origin 
			,String originName 
			,String billNo 
			
			,String cUsercode//=com.justep.system.context.ContextHelper.getOperator().getCode();
			,String cUsername//=com.justep.system.context.ContextHelper.getOperator().getName();
			,String userId //= com.justep.system.context.ContextHelper.getOperator().getID();
			,String enterpriseNo //= this.getEnterpriseNo();
			,String enterpriseName //= this.getEnterpriseName();
			){
		
		AccountVoucher obj = new AccountVoucher();
		String fID = Utils.getUUID();
		obj.setfID(fID);
		
		//单号
		/*
		Map<String,Object> map = usercenterService.getBillParam(billType, enterpriseNo);
		String billTypeName = (String) map.get("billTypeName");
//		String systemCode = (String) map.get("systemCode");
		int flowType = (int) map.get("flowType");
//		String revOpay = (String) map.get("revOpay");
		int direction = (int) map.get("direction");
//		String costingCode = (String) map.get("costingCode");
		String autoCode = (String) map.get("autoCode");
		String origin = (String) map.get("origin");
		String originName = (String) map.get("originName");
		if("Y".equals(autoCode)){
			String billNo = (String) map.get("billNo");
			obj.setVoucherNo(billNo);
		}
		*/
		if("Y".equals(autoCode)){
			obj.setVoucherNo(billNo);
		}
		
		obj.setSystemCode(systemCode);//APPID
		
		obj.setBillType(billType);
		obj.setBillTypeName(billTypeName);
		obj.setFlowType(flowType);

		obj.setDirection(direction);
		obj.setOrigin(origin);
		obj.setOriginName(originName);
		
		obj.setState("active");
		obj.setStatus("open");
		obj.setAudit("active");
		obj.setOrderDate(Utils.getCurrentDate());
		
		obj.setDebitAmount(BigDecimal.ZERO);
		obj.setCreditAmount(BigDecimal.ZERO);
		obj.setAttachQuantity(0);
		
		obj.setcUsercode(cUsercode);
		obj.setcUsername(cUsername);
		obj.setcDatetime(Utils.getCurrentDateTime());
		obj.setUserId(userId);
		obj.setEnterpriseNo(enterpriseNo);
		obj.setEnterpriseName(enterpriseName);
		
		obj.setDetailsCount(0);
		obj.setMaxDetailNo(0);

		obj.setVersion(0);
		
		
		return obj;
	}
	
	//不生成编号（待到底稿生成凭证时写入编号）
	@Override
	public AccountVoucher packing(
			String origin 
			,String originName 
			,String originNo 
			,String billType
			,String billTypeName 
			,String systemCode 
			,int flowType 
			,int direction 
			
			,String cUsercode//=com.justep.system.context.ContextHelper.getOperator().getCode();
			,String cUsername//=com.justep.system.context.ContextHelper.getOperator().getName();
			,String userId //= com.justep.system.context.ContextHelper.getOperator().getID();
			,String enterpriseNo //= this.getEnterpriseNo();
			,String enterpriseName //= this.getEnterpriseName();
			){
		
		AccountVoucher obj = new AccountVoucher();
		String fID = Utils.getUUID();
		obj.setfID(fID);
		
		obj.setFormalFlag(0);//分录底稿
		obj.setOriginNo(originNo);
				
		obj.setSystemCode(systemCode);//APPID
		
		obj.setBillType(billType);
		obj.setBillTypeName(billTypeName);
		obj.setFlowType(flowType);

		obj.setDirection(direction);
		obj.setOrigin(origin);
		obj.setOriginName(originName);
		
		obj.setState("active");
		obj.setStatus("open");
		obj.setAudit("active");
		obj.setOrderDate(Utils.getCurrentDate());
		
		obj.setDebitAmount(BigDecimal.ZERO);
		obj.setCreditAmount(BigDecimal.ZERO);
		obj.setAttachQuantity(0);
		
		obj.setcUsercode(cUsercode);
		obj.setcUsername(cUsername);
		obj.setcDatetime(Utils.getCurrentDateTime());
		obj.setUserId(userId);
		obj.setEnterpriseNo(enterpriseNo);
		obj.setEnterpriseName(enterpriseName);
		
		obj.setDetailsCount(0);
		obj.setMaxDetailNo(0);

		obj.setVersion(0);
		
		
		return obj;
	}
	
	@Override
    public void afterInsert(AccountVoucher obj){

	}
	
	@Override
    public void beforeDelete(String fID){
		
	}
	
	@Override
	public JSONObject newData(JSONObject data) {
		return dao.create(data);
	}
	
	@Override
	public JSONObject deleteData(JSONObject param) {
		
		JSONArray ids = param.getJSONArray("ids");
		for(int i=0;i<ids.size();i++){
			String id = ids.getString(i);
			//这里可以增加是否可删除的判断
			
			//首先删除子表
			List<AccountVoucherDetail> sods = detailDao.getByMasterID(id);
			for(AccountVoucherDetail sod:sods){
				detailDao.delete(sod.getfID());
			}

			//然后删除主表
			dao.delete(id);
		}

		JSONObject data = new JSONObject();
		data.put("ids", ids);
		
		JSONObject json = new JSONObject();
		json.put("code", 0);
		json.put("msg", "success");
		json.put("data", data);
		
		return json;
	}
	
	@Override
	public JSONObject saveData(JSONObject param) {
		// TODO Auto-generated method stub
		JSONObject data;
		try {
			//保存主表
			data = this.save(param);
			
			//保存从表
			JSONArray slaves = param.getJSONArray("slaves");
			JSONObject slaveParam = slaves.getJSONObject(0);
			
			JSONObject slaveData = this.saveDetail(slaveParam);
			
			JSONArray slaveDatas = new JSONArray();
			slaveDatas.add(slaveData);
			data.put("slaves", slaveDatas);
					
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", data);
			
			return json;
			
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			
			return json;
		} 
	}
	
	@Override
	public JSONObject queryData(JSONObject param) {
		// TODO Auto-generated method stub
		try {
			JSONObject jsonTable = dao.query(param);
			
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", jsonTable);
			
			return json;
		} catch (SQLException e) {
			e.printStackTrace();
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			return json;
		}
	}
	
	@Override
	public JSONObject validData(JSONObject param) {
		// TODO Auto-generated method stub
		return null;
	}

	//新增子表
	@Override
	public JSONObject newDataDetail(JSONObject data) {
		return detailDao.create(data);
	}
	
	//查询子表
	@Override
	public JSONObject queryDataDetail(JSONObject param) {
		// TODO Auto-generated method stub
		try {
			JSONObject jsonTable = detailDao.query(param);
			
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", jsonTable);
			
			return json;
		} catch (SQLException e) {
			e.printStackTrace();
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			return json;
		}
	}
	
	
	@Override
	public AccountVoucher insert(
			String billType
			,String billTypeName 
			,String systemCode 
			,int flowType 
			,int direction 
			,String autoCode 
			,String origin 
			,String originName 
			,String originNo 
			,String billNo 
			
			, BigDecimal debitAmount      //借方金额
			, BigDecimal creditAmount       //贷方金额
			, String wordsAmount       //大写金额
			, int attachQuantity //附件数量
			
			,String cUsercode//=com.justep.system.context.ContextHelper.getOperator().getCode();
			,String cUsername//=com.justep.system.context.ContextHelper.getOperator().getName();
			,String userId //= com.justep.system.context.ContextHelper.getOperator().getID();
			,String enterpriseNo //= this.getEnterpriseNo();
			,String enterpriseName //= this.getEnterpriseName();
			){
		
		AccountVoucher obj = new AccountVoucher();
		String fID = Utils.getUUID();
		obj.setfID(fID);
		
		//单号
		/*
		Map<String,Object> map = usercenterService.getBillParam(billType, enterpriseNo);
		String billTypeName = (String) map.get("billTypeName");
//		String systemCode = (String) map.get("systemCode");
		int flowType = (int) map.get("flowType");
//		String revOpay = (String) map.get("revOpay");
		int direction = (int) map.get("direction");
//		String costingCode = (String) map.get("costingCode");
		String autoCode = (String) map.get("autoCode");
		String origin = (String) map.get("origin");
		String originName = (String) map.get("originName");
		if("Y".equals(autoCode)){
			String billNo = (String) map.get("billNo");
			obj.setVoucherNo(billNo);
		}
		*/
		if("Y".equals(autoCode)){
			obj.setVoucherNo(billNo);
		}
		
		obj.setSystemCode(systemCode);//APPID
		
		obj.setBillType(billType);
		obj.setBillTypeName(billTypeName);
		obj.setFlowType(flowType);

		obj.setDirection(direction);
		obj.setOrigin(origin);
		obj.setOriginName(originName);
		
		obj.setState("active");
		obj.setStatus("open");
		obj.setAudit("active");
		obj.setOrderDate(Utils.getCurrentDate());
		
		obj.setDebitAmount(BigDecimal.ZERO);
		obj.setCreditAmount(BigDecimal.ZERO);
		obj.setAttachQuantity(0);
		
		obj.setcUsercode(cUsercode);
		obj.setcUsername(cUsername);
		obj.setcDatetime(Utils.getCurrentDateTime());
		obj.setUserId(userId);
		obj.setEnterpriseNo(enterpriseNo);
		obj.setEnterpriseName(enterpriseName);
		
		obj.setDetailsCount(0);
		obj.setMaxDetailNo(0);

		obj.setVersion(0);
		
		
		return obj;
	}


}
